package de.altitude.cimuelle.commandhandles;

import de.altitude.cimuelle.Config;
import de.altitude.cimuelle.MessageBundle;
import de.altitude.cimuelle.db.DatabaseManager;
import de.altitude.cimuelle.db.DatabasePlayerInfo;
import de.altitude.cimuelle.utils.StringUtils;
import de.altitudecustomcommands.Player;
import de.altitudecustomcommands.exceptions.ServerNotFoundException;
import de.altitudecustomcommands.playerHandler;
import de.altitudecustomcommands.serverInformations;
import org.apache.log4j.Logger;

import java.util.Calendar;
import java.util.HashMap;
import java.util.List;

import static de.altitude.cimuelle.utils.ServerOperations.sendServerMessage;
import static de.altitude.cimuelle.utils.ServerOperations.sendServerWhisper;

/**
 * Class description:
 * processes chat
 * User: cybernaut
 * Date: 07.10.11
 * Time: 21:37
 */
public class TypeChatHandle {
    private final static Logger LOGGER = Logger.getLogger("TypeChatHandle");

    private final playerHandler playerList;
    private final serverInformations server;
    private Config config;

    public TypeChatHandle(playerHandler playerList, serverInformations server) {

        this.playerList = playerList;
        this.server = server;
        this.config = Config.getInstance();
    }

    public void typeChat(String port, int playerId, String chatString) {
        Player[] players = playerList.getPlayersByPortAndId(port, playerId);

        if (config.isDebug()) {
            StringBuilder dm = new StringBuilder();
            dm.append(Calendar.getInstance().getTime()).append(":").append(port).append(":");
            for (Player p : players) {
                dm.append(p.getName());
            }
            dm.append(":").append(chatString);
            LOGGER.info(dm);
        }

        if (config.isChatCommandEnabledByPort(port)) {
            if (config.isCoopActiveByPort(port)) {
                // coop
                if ("!TopRanks".equals(chatString)) {
                    chatTopPlayers(config, port, players);
                } else if ("!TCRank".equals(chatString)) {
                    chatMyTCRank(config, port, players);
                } else if (chatString.startsWith("!SeeTCRank")) {
                    chatTCPlayerRank(config, chatString, "!SeeTCRank{", port, players);
                } else if ("!Rank".equals(chatString)) {
                    chatMyRank(config, port, players);
                } else if (chatString.startsWith("!SeeRank")) {
                    chatPlayerRank(config, chatString, "!SeeRank{", port, players);
                } else if ("!Session".equals(chatString)) {
                    chatMySession(config, port, players);
                } else if ("!Cmd".equals(chatString)) {
                    chatShowCmd(port, players, MessageBundle.getString("listCommandsCoop"));
                }
            } else {
                // ball
                if ("!TopRanks".equals(chatString)) {
                    chatTopPlayers(config, port, players);
                } else if ("!MyTCRank".equals(chatString)) {
                    chatMyTCRank(config, port, players);
                } else if (chatString.startsWith("!TCPlayerRank")) {
                    chatTCPlayerRank(config, chatString, "!TCPlayerRank{", port, players);
                } else if ("!MyRank".equals(chatString)) {
                    chatMyRank(config, port, players);
                } else if (chatString.startsWith("!PlayerRank")) {
                    chatPlayerRank(config, chatString, "!PlayerRank{", port, players);
                } else if ("!MyStats".equals(chatString)) {
                    chatMyStat(port, players);
                } else if (chatString.startsWith("!PlayerStats")) {
                    chatPlayerStat(chatString, "!PlayerStats{", port, players);
                } else if ("!Cmd".equals(chatString)) {
                    chatShowCmd(port, players, MessageBundle.getString("listCommandsBall"));
                }
            }
        }
        chatGetResponseFromConfig(port, chatString, config, players);
    }

    private void chatShowCmd(String port, Player[] players, String message) {
        for (Player p : players) {
            sendServerWhisper(port, p.getName(), message);
        }
    }

    private void chatTopPlayers(Config config, String port, Player[] players) {
        List<DatabasePlayerInfo> playerRankInfo;
        String orderBy = config.getConfigByPort(port, "rankingOrder", "turretKills");
        playerRankInfo = DatabaseManager.getInstance().getRankBy(port, Integer.parseInt(config.getConfigByPort(port, "TopRanks", "9")) + 1, orderBy);
        StringBuilder sb = new StringBuilder();
        StringUtils.buildRankString(config, port, playerRankInfo, sb);
        for (Player p : players) {
            sendServerWhisper(port, p.getName(), sb.toString());
        }
    }


    private void chatMyTCRank(Config config, String port, Player[] players) {
        for (Player p : players) {
            List<DatabasePlayerInfo> playerRankInfo;
            String orderBy = config.getConfigByPort(port, "rankingOrder", "turretKills");
            playerRankInfo = DatabaseManager.getInstance().getMiddleRankBy(port, Integer.parseInt(config.getConfigByPort(port, "TCRankCount", "4")) + 1, p, orderBy);
            StringBuilder sb = new StringBuilder();
            StringUtils.buildRankString(config, port, playerRankInfo, sb);
            sendServerWhisper(port, p.getName(), sb.toString());
        }
    }

    private void chatTCPlayerRank(Config config, String chatString, String port, String commandPart, Player[] players) {
        String name = StringUtils.removeStringAndBracket(chatString, commandPart);
        Player seePlayer = playerList.getPlayerByName(name);
        for (Player p : players) {
            List<DatabasePlayerInfo> playerRankInfo;
            String orderBy = config.getConfigByPort(port, "rankingOrder", "turretKills");
            playerRankInfo = DatabaseManager.getInstance().getMiddleRankBy(port, Integer.parseInt(config.getConfigByPort(port, "TCRankCount", "4")) + 1, seePlayer, orderBy);
            StringBuilder sb = new StringBuilder();
            StringUtils.buildRankString(config, port, playerRankInfo, sb);
            sendServerWhisper(port, p.getName(), StringUtils.addslashes(sb.toString()));
        }
    }

    private void chatMyRank(Config config, String port, Player[] players) {
        for (Player p : players) {
            List<DatabasePlayerInfo> playerRankInfo;
            String orderBy = config.getConfigByPort(port, "rankingOrder", "turretKills");
            playerRankInfo = DatabaseManager.getInstance().getRankByVapor(p, orderBy);
            StringBuilder sb = new StringBuilder();
            StringUtils.buildRankString(config, port, playerRankInfo, sb);
            sendServerWhisper(port, p.getName(), StringUtils.addslashes(sb.toString()));
        }
    }

    private void chatPlayerRank(Config config, String chatString, String commandPart, String port, Player[] players) {
        String name = StringUtils.removeStringAndBracket(chatString, commandPart);
        List<DatabasePlayerInfo> playerRankInfo;
        String orderBy = config.getConfigByPort(port, "rankingOrder", "turretKills");
        playerRankInfo = DatabaseManager.getInstance().getRankByName(port, name, orderBy);
        StringBuilder sb = new StringBuilder();
        StringUtils.buildRankString(config, port, playerRankInfo, sb);
        for (Player p : players) {
            if (sb.toString().isEmpty()) {
                sb.append("Unknown Name");
            }
            sendServerWhisper(port, p.getName(), StringUtils.addslashes(sb.toString()));
        }
    }

    private void chatMySession(Config config, String port, Player[] players) {
        for (Player player : players) {
            HashMap<String, String> map = new HashMap<String, String>();
            map.put("PLAYERNAME", player.getName());
            map.put("DESTROYEDTURRETSSUM", String.valueOf(player.getStats().getDestroyedTurrets()));
            map.put("DESTROYEDTURRETSMAP", String.valueOf(player.getStats().getDestroyedTurretsByMap()));
            map.put("DESTROYEDBASESSUM", String.valueOf(player.getStats().getDestroyedBases()));
            map.put("DESTROYEDBASESMAP", String.valueOf(player.getStats().getDestroyedBasesByMap()));
            map.put("KILLEDPLANESSUM", String.valueOf(player.getStats().getKilledPlanes()));
            map.put("KILLEDPLANESMAP", String.valueOf(player.getStats().getKilledPlanesByMap()));

            StringBuilder sb = new StringBuilder();
            sb.append(MessageBundle.getString("wmySessionStats1", map));

            if (config.isDebug()) {
                LOGGER.info(port + ":Sending info to player:" + sb.toString());
            }
            sendServerWhisper(port, player.getName(), sb.toString());
        }
    }


    private void chatMyStat(String port, Player[] players) {
        //ball only
        for (Player p : players) {
            getShowStatFor(port, p, p);
        }
    }

    private void chatPlayerStat(String chatString, String commandPart, String port, Player[] players) {
        //ball only
        String name = StringUtils.removeStringAndBracket(chatString, commandPart);
        Player seePlayer = playerList.getPlayerByName(name);
        for (Player p : players) {
            getShowStatFor(port, p, seePlayer);
        }
    }


    private void getShowStatFor(String port, Player p, Player seePlayer) {
        DatabasePlayerInfo playerRankInfo = DatabaseManager.getInstance().getPlayerStats(port, seePlayer);
        StringBuilder sb = new StringBuilder();
        StringUtils.buildStatsString(playerRankInfo, sb);
        sendServerWhisper(port, p.getName(), StringUtils.addslashes(sb.toString()));
    }

    private void chatGetResponseFromConfig(String port, String chatString, Config config, Player[] players) {
        char controlChar = chatString.charAt(0);
        chatString = chatString.substring(1);

        if (config.isChatProperty(port, chatString)) {

            if (controlChar == '?') {
                for (Player p : players) {
                    try {
                        if (server.getServerByPort(Integer.parseInt(port)).isAdminByVapor(p.getVapor())) {
                            sendServerMessage(port, config.getChatMessage(port, chatString));
                        }
                    } catch (ServerNotFoundException e) {
                        e.printStackTrace();
                        LOGGER.error(port + ":" + e, e);
                    }
                }
            } else if (controlChar == '!') {
                for (Player p : players) {
                    sendServerWhisper(port, p.getName(), config.getChatMessage(port, chatString));
                }
            }
        }
    }


}
